from selenium import webdriver
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from webdriver_manager.firefox import GeckoDriverManager
import time
import logging
from config import WEBSITE_CONFIG, BROWSER_CONFIG, USER_CONFIG
import random

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('automation.log'),
        logging.StreamHandler()
    ]
)

class FirefoxAutomation:
    def __init__(self):
        try:
            # 配置Firefox选项
            self.options = Options()
            self.options.set_preference("plugin.state.flash", 2)
            
            if BROWSER_CONFIG['headless']:
                self.options.add_argument('--headless')
            
            # 创建Firefox驱动
            self.driver = webdriver.Firefox(
                service=Service(GeckoDriverManager().install()),
                options=self.options
            )
            
            # 设置窗口大小
            self.driver.set_window_size(*BROWSER_CONFIG['window_size'])
            
            # 设置隐式等待时间
            self.driver.implicitly_wait(BROWSER_CONFIG['implicit_wait'])
            
            logging.info("浏览器初始化成功")
            
        except Exception as e:
            logging.error(f"浏览器初始化失败: {str(e)}")
            raise
    
    def wait_for_element(self, by, value, timeout=None):
        """等待元素出现"""
        if timeout is None:
            timeout = BROWSER_CONFIG['timeout']
        try:
            element = WebDriverWait(self.driver, timeout).until(
                EC.presence_of_element_located((by, value))
            )
            return element
        except TimeoutException:
            logging.error(f"等待元素超时: {value}")
            return None
    
    def click_element(self, by, value):
        """点击元素"""
        try:
            element = self.wait_for_element(by, value)
            element.click()
        except Exception as e:
            logging.error(f"点击元素失败: {str(e)}")
    
    def login(self):
        """模拟登录功能"""
        try:
            # 构建完整的登录URL
            login_url = WEBSITE_CONFIG['url'] + WEBSITE_CONFIG['login_url']
            logging.info(f"正在访问登录页面: {login_url}")
            
            self.driver.get(login_url)
            
            # 等待页面完全加载
            logging.info("等待页面完全加载...")
            time.sleep(5)  # 增加初始等待时间
            
            # 等待页面加载完成
            WebDriverWait(self.driver, 10).until(
                lambda driver: driver.execute_script('return document.readyState') == 'complete'
            )
            logging.info("页面加载完成")
            
            # 查找所有iframe
            iframes = self.driver.find_elements(By.TAG_NAME, "iframe")
            logging.info(f"找到 {len(iframes)} 个iframe")
            
            # 遍历所有iframe，找到正确的登录iframe
            login_iframe = None
            for iframe in iframes:
                # 获取iframe属性
                iframe_id = iframe.get_attribute('id')
                iframe_name = iframe.get_attribute('name')
                
                # 跳过反外挂iframe
                if "antiplug" in str(iframe_id).lower() or "antiplug" in str(iframe_name).lower():
                    continue
                
                # 检查是否是登录iframe
                if "login" in str(iframe_id).lower() or "login" in str(iframe_name).lower():
                    login_iframe = iframe
                    break
            
            if not login_iframe:
                logging.error("未找到登录iframe")
                return False
            
            # 切换到登录iframe
            self.driver.switch_to.frame(login_iframe)
            
            # 等待并查找switcher_plogin元素
            try:
                element = WebDriverWait(self.driver, 15).until(
                    EC.presence_of_element_located((By.ID, "switcher_plogin"))
                )
                element.click()
                logging.info("已点击切换登录按钮")
            except TimeoutException:
                logging.error("未找到switcher_plogin元素")
                return False
            
            # 等待并填写用户名
            try:
                username_field = WebDriverWait(self.driver, 10).until(
                    EC.presence_of_element_located((By.NAME, WEBSITE_CONFIG['username_field']))
                )
                # 模拟用户输入用户名
                for char in USER_CONFIG['username']:
                    username_field.send_keys(char)
                    time.sleep(random.uniform(0.1, 0.3))  # 随机延迟0.1-0.3秒
                logging.info("已填写用户名")
                time.sleep(1)  # 输入完成后等待1秒
            except TimeoutException:
                logging.error("未找到用户名输入框")
                return False
            
            # 等待并填写密码
            try:
                password_field = WebDriverWait(self.driver, 10).until(
                    EC.presence_of_element_located((By.NAME, WEBSITE_CONFIG['password_field']))
                )
                # 模拟用户输入密码
                for char in USER_CONFIG['password']:
                    password_field.send_keys(char)
                    time.sleep(random.uniform(0.1, 0.3))  # 随机延迟0.1-0.3秒
                logging.info("已填写密码")
                time.sleep(1)  # 输入完成后等待1秒
            except TimeoutException:
                logging.error("未找到密码输入框")
                return False
            
            # 点击登录按钮
            try:
                login_button = WebDriverWait(self.driver, 10).until(
                    EC.presence_of_element_located((By.ID, WEBSITE_CONFIG['login_button']))
                )
                time.sleep(1)  # 点击前等待1秒
                login_button.click()
                logging.info("已点击登录按钮")
            except TimeoutException:
                logging.error("未找到登录按钮")
                return False
            
            # 等待登录完成
            time.sleep(3)
            
            # 切换回主文档
            self.driver.switch_to.default_content()
            
            # 检查是否登录成功
            if self.check_login_status():
                logging.info("登录成功")
                # 等待第一次页面跳转
                time.sleep(3)
                # 等待第一次页面加载完成
                WebDriverWait(self.driver, 10).until(
                    lambda driver: driver.execute_script('return document.readyState') == 'complete'
                )
                logging.info("第一次页面跳转完成")
                
                # 等待第二次页面跳转
                time.sleep(3)
                # 等待第二次页面加载完成
                WebDriverWait(self.driver, 10).until(
                    lambda driver: driver.execute_script('return document.readyState') == 'complete'
                )
                logging.info("第二次页面跳转完成")
            else:
                logging.error("登录失败")
            
            # 检查是否还存在switcher_plogin元素
            try:
                # 重新查找登录iframe
                iframes = self.driver.find_elements(By.TAG_NAME, "iframe")
                logging.info(f"找到 {len(iframes)} 个iframe")
                login_iframe = None
                for iframe in iframes:
                    iframe_id = iframe.get_attribute('id')
                    iframe_name = iframe.get_attribute('name')
                    logging.info(f"检查iframe: id={iframe_id}, name={iframe_name}")
                    if "antiplug" in str(iframe_id).lower() or "antiplug" in str(iframe_name).lower():
                        continue
                    if "iframe_app" in str(iframe_id).lower() or "iframe_app" in str(iframe_name).lower():
                        login_iframe = iframe
                        logging.info(f"找到登录iframe: id={iframe_id}, name={iframe_name}")
                        break
                
                if login_iframe:
                    # 切换到登录iframe
                    self.driver.switch_to.frame(login_iframe)
                    logging.info("已切换到登录iframe")
                    
                    # 在登录iframe中查找嵌套的iframe
                    nested_iframes = self.driver.find_elements(By.TAG_NAME, "iframe")
                    logging.info(f"在登录iframe中找到 {len(nested_iframes)} 个嵌套iframe")
                    nested_login_iframe = None
                    for iframe in nested_iframes:
                        iframe_id = iframe.get_attribute('id')
                        iframe_name = iframe.get_attribute('name')
                        logging.info(f"检查嵌套iframe: id={iframe_id}, name={iframe_name}")
                        if "antiplug" in str(iframe_id).lower() or "antiplug" in str(iframe_name).lower():
                            continue
                        if "login" in str(iframe_id).lower() or "login" in str(iframe_name).lower():
                            nested_login_iframe = iframe
                            logging.info(f"找到嵌套登录iframe: id={iframe_id}, name={iframe_name}")
                            break
                    
                    if nested_login_iframe:
                        # 切换到嵌套的登录iframe
                        self.driver.switch_to.frame(nested_login_iframe)
                        logging.info("已切换到嵌套的登录iframe")
                        
                        # 打印嵌套iframe的HTML内容
                        try:
                            html_content = self.driver.page_source
                            logging.info("嵌套iframe的HTML内容:")
                            logging.info(html_content)
                        except Exception as e:
                            logging.error(f"获取嵌套iframe HTML内容时出错: {str(e)}")
                        
                        # 在嵌套的iframe中查找switcher_plogin元素
                        try:
                            element = WebDriverWait(self.driver, 5).until(
                                EC.presence_of_element_located((By.ID, "switcher_plogin"))
                            )
                            logging.info("检测到switcher_plogin元素，开始二次登录")
                            
                            # 点击切换登录按钮
                            element.click()
                            logging.info("已点击切换登录按钮")
                            
                            # 重新输入用户名
                            username_field = WebDriverWait(self.driver, 10).until(
                                EC.presence_of_element_located((By.NAME, WEBSITE_CONFIG['username_field']))
                            )
                            username_field.clear()
                            logging.info("开始输入用户名")
                            for char in USER_CONFIG['username']:
                                username_field.send_keys(char)
                                time.sleep(random.uniform(0.1, 0.3))
                            logging.info("用户名输入完成")
                            
                            # 重新输入密码
                            password_field = WebDriverWait(self.driver, 10).until(
                                EC.presence_of_element_located((By.NAME, WEBSITE_CONFIG['password_field']))
                            )
                            password_field.clear()
                            logging.info("开始输入密码")
                            for char in USER_CONFIG['password']:
                                password_field.send_keys(char)
                                time.sleep(random.uniform(0.1, 0.3))
                            logging.info("密码输入完成")
                            
                            # 点击登录按钮
                            login_button = WebDriverWait(self.driver, 10).until(
                                EC.presence_of_element_located((By.ID, WEBSITE_CONFIG['login_button']))
                            )
                            time.sleep(1)
                            login_button.click()
                            logging.info("已点击登录按钮，等待登录完成")
                            
                            # 等待登录完成
                            time.sleep(3)
                            
                            # 切换回主文档
                            self.driver.switch_to.default_content()
                            logging.info("已切换回主文档")
                            
                            # 再次检查登录状态
                            if self.check_login_status():
                                logging.info("二次登录成功")
                                return True
                            else:
                                logging.error("二次登录失败")
                                return False
                        except TimeoutException:
                            logging.info("未找到switcher_plogin元素，无需二次登录")
                            # 切换回主文档
                            self.driver.switch_to.default_content()
                            return True
                    else:
                        logging.info("未找到嵌套的登录iframe，无需二次登录")
                        # 切换回主文档
                        self.driver.switch_to.default_content()
                        return True
                else:
                    logging.info("未找到登录iframe，无需二次登录")
                    return True
            except Exception as e:
                logging.error(f"检查switcher_plogin元素时出现错误: {str(e)}")
                # 确保切换回主文档
                try:
                    self.driver.switch_to.default_content()
                except:
                    pass
                return False
            
            return True
                
        except Exception as e:
            logging.error(f"登录过程中出现错误: {str(e)}")
            return False
    
    def check_login_status(self):
        """检查登录状态"""
        try:
            # 这里需要根据实际网站修改检查登录状态的方法
            # 例如检查特定元素是否存在
            return True
        except Exception as e:
            logging.error(f"检查登录状态时出错: {str(e)}")
            return False
    
    def close(self):
        """关闭浏览器"""
        try:
            self.driver.quit()
            logging.info("浏览器已关闭")
        except Exception as e:
            logging.error(f"关闭浏览器时出错: {str(e)}")

    def check_element_exists(self, by, value, timeout=None):
        """
        检查元素是否存在
        
        Args:
            by: 定位方式（如 By.ID, By.XPATH 等）
            value: 定位值
            timeout: 超时时间（可选）
            
        Returns:
            bool: 如果元素存在返回 True，否则返回 False
        """
        try:
           

            if timeout is None:
                timeout = BROWSER_CONFIG['timeout']

            # 使用 find_elements 方法查找元素
            elements = self.driver.find_elements(by, value)
            
            # 如果找到至少一个元素，返回 True
            return len(elements) > 0
            
        except Exception as e:
            logging.error(f"检查元素是否存在时出错: {str(e)}")
            return False

def main():
    automation = None
    try:
        automation = FirefoxAutomation()
        
        if automation.login():
            logging.info("登录成功，浏览器保持打开状态")
            # 这里可以添加其他操作
        else:
            logging.error("登录失败")
    
    except Exception as e:
        logging.error(f"程序运行出错: {str(e)}")
    
    # 移除自动关闭浏览器的代码
    # 让用户手动决定何时关闭浏览器

if __name__ == "__main__":
    main() 